﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GeneticAlgorythm.Algorythm
{
    public sealed class RandomGenerator{

        private static readonly RandomGenerator _instance = new RandomGenerator();
        private static Random _random;

        private RandomGenerator() 
        {
            _random = new Random();
        }

        public static RandomGenerator getInstance()
        {
            return _instance;

        }
        public int generateRandomIntegerFromZeroTo(int maxValue) 
        {
            return _random.Next(maxValue);
        }

        public PermutationChromosome generateNewIntegerPermutationChromosome(int sizeAndMaxValue)
        {
            List<int> genes = new List<int>();
            for (int i = 0; i < sizeAndMaxValue; i++)
            {
                genes.Add(differentIntegerFromOneTo(genes,sizeAndMaxValue));
 
            }
            return new PermutationChromosome(genes);
        }

        private int differentIntegerFromOneTo(List<int> genes, int sizeAndMaxValue) 
        {
            int rand=_random.Next(1, sizeAndMaxValue+1);

            while(genes.Contains(rand)) {
                rand=_random.Next(1, sizeAndMaxValue+1);
            }
            return rand;

        }

        public List<bool> generateBitVector(int size)
        {
            List<bool> bitVector = new List<bool>();

            for (int i = 0; i < size; i++)
            {
                bitVector.Add(generateRandomBoolean());
            }

            return bitVector;
        }

        public bool generateRandomBoolean()
        {
            return _random.Next(2).Equals(0);
        }

        public Crossover generateCrossoverType()
        {
            int value = _random.Next(4);
            switch(value)
            {
                case 0:
                    return new CycleCrossover();
                case 1:
                    return new OrderCrossover();
                case 2:
                    return new PartiallyMatchedCrossover();
                case 3:
                    return new UniformOrderBasedCrossover();
                default:
                    return null;

            }
        }
    }
}
